home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_068 / mg1b / basic.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  8KB  |  371 lines

  1. /*
  2.  *        Basic cursor motion commands.
  3.  * 
  4.  * The routines in this file are the basic
  5.  * command functions for moving the cursor around on
  6.  * the screen, setting mark, and swapping dot with
  7.  * mark. Only moves between lines, which might make the
  8.  * current buffer framing bad, are hard.
  9.  */
  10. #include    "def.h"
  11.  
  12. VOID    setgoal();
  13.  
  14. /*
  15.  * Go to beginning of line.
  16.  */
  17. /*ARGSUSED*/
  18. gotobol(f, n, k) {
  19.     curwp->w_doto  = 0;
  20.     return (TRUE);
  21. }
  22.  
  23. /*
  24.  * Move cursor backwards. Do the
  25.  * right thing if the count is less than
  26.  * 0. Error if you try to move back from
  27.  * the beginning of the buffer.
  28.  */
  29. /*ARGSUSED*/
  30. backchar(f, n, k) register int n; {
  31.     register LINE    *lp;
  32.  
  33.     if (n < 0)
  34.         return (forwchar(f, -n, k));
  35.     while (n--) {
  36.         if (curwp->w_doto == 0) {
  37.             if ((lp=lback(curwp->w_dotp)) == curbp->b_linep) {
  38.                 if (k != KRANDOM)
  39.                     ewprintf("Beginning of buffer");
  40.                 return (FALSE);
  41.             }
  42.             curwp->w_dotp  = lp;
  43.             curwp->w_doto  = llength(lp);
  44.             curwp->w_flag |= WFMOVE;
  45.         } else
  46.             curwp->w_doto--;
  47.     }
  48.     return (TRUE);
  49. }
  50.  
  51. /*
  52.  * Go to end of line.
  53.  */
  54. /*ARGSUSED*/
  55. gotoeol(f, n, k) {
  56.     curwp->w_doto  = llength(curwp->w_dotp);
  57.     return (TRUE);
  58. }
  59.  
  60. /*
  61.  * Move cursor forwards. Do the
  62.  * right thing if the count is less than
  63.  * 0. Error if you try to move forward
  64.  * from the end of the buffer.
  65.  */
  66. /*ARGSUSED*/
  67. forwchar(f, n, k) register int n; {
  68.     if (n < 0)
  69.         return (backchar(f, -n, k));
  70.     while (n--) {
  71.         if (curwp->w_doto == llength(curwp->w_dotp)) {
  72.             if (curwp->w_dotp == curbp->b_linep) {
  73.                 if (k != KRANDOM)
  74.                     ewprintf("End of buffer");
  75.                 return (FALSE);
  76.             }
  77.             curwp->w_dotp  = lforw(curwp->w_dotp);
  78.             curwp->w_doto  = 0;
  79.             curwp->w_flag |= WFMOVE;
  80.         } else
  81.             curwp->w_doto++;
  82.     }
  83.     return (TRUE);
  84. }
  85.  
  86. /*
  87.  * Go to the beginning of the
  88.  * buffer. Setting WFHARD is conservative,
  89.  * but almost always the case.
  90.  */
  91. gotobob(f, n, k) {
  92.     (VOID) setmark(f, n, k) ;
  93.     curwp->w_dotp  = lforw(curbp->b_linep);
  94.     curwp->w_doto  = 0;
  95.     curwp->w_flag |= WFHARD;
  96.     return (TRUE);
  97. }
  98.  
  99. /*
  100.  * Go to the end of the buffer.
  101.  * Setting WFHARD is conservative, but
  102.  * almost always the case.
  103.  */
  104. gotoeob(f, n, k) {
  105.     (VOID) setmark(f, n, k) ;
  106.     curwp->w_dotp  = curbp->b_linep;
  107.     curwp->w_doto  = 0;
  108.     curwp->w_flag |= WFHARD;
  109.     return (TRUE);
  110. }
  111.  
  112. /*
  113.  * Move forward by full lines.
  114.  * If the number of lines to move is less
  115.  * than zero, call the backward line function to
  116.  * actually do it. The last command controls how
  117.  * the goal column is set.
  118.  */
  119. /*ARGSUSED*/
  120. forwline(f, n, k) {
  121.     register LINE    *dlp;
  122.  
  123.     if (n < 0)
  124.         return (backline(f, -n, KRANDOM));
  125.     if ((lastflag&CFCPCN) == 0)        /* Fix goal.        */
  126.         setgoal();
  127.     thisflag |= CFCPCN;
  128.     dlp = curwp->w_dotp;
  129.     while (n-- && dlp!=curbp->b_linep)
  130.         dlp = lforw(dlp);
  131.     curwp->w_dotp  = dlp;
  132.     curwp->w_doto  = getgoal(dlp);
  133.     curwp->w_flag |= WFMOVE;
  134.     return (TRUE);
  135. }
  136.  
  137. /*
  138.  * This function is like "forwline", but
  139.  * goes backwards. The scheme is exactly the same.
  140.  * Check for arguments that are less than zero and
  141.  * call your alternate. Figure out the new line and
  142.  * call "movedot" to perform the motion.
  143.  */
  144. /*ARGSUSED*/
  145. backline(f, n, k) {
  146.     register LINE    *dlp;
  147.  
  148.     if (n < 0)
  149.         return (forwline(f, -n, KRANDOM));
  150.     if ((lastflag&CFCPCN) == 0)        /* Fix goal.        */
  151.         setgoal();
  152.     thisflag |= CFCPCN;
  153.     dlp = curwp->w_dotp;
  154.     while (n-- && lback(dlp)!=curbp->b_linep)
  155.         dlp = lback(dlp);
  156.     curwp->w_dotp  = dlp;
  157.     curwp->w_doto  = getgoal(dlp);
  158.     curwp->w_flag |= WFMOVE;
  159.     return (TRUE);
  160. }
  161.  
  162. /*
  163.  * Set the current goal column,
  164.  * which is saved in the external variable "curgoal",
  165.  * to the current cursor column. The column is never off
  166.  * the edge of the screen; it's more like display then
  167.  * show position.
  168.  */
  169. VOID
  170. setgoal() {
  171.  
  172.     curgoal = getcolpos() - 1;        /* Get the position.    */
  173.     if (curgoal >= ncol)            /* Chop to tty width.    */
  174.         curgoal = ncol-1;
  175. }
  176.  
  177. /*
  178.  * This routine looks at a line (pointed
  179.  * to by the LINE pointer "dlp") and the current
  180.  * vertical motion goal column (set by the "setgoal"
  181.  * routine above) and returns the best offset to use
  182.  * when a vertical motion is made into the line.
  183.  */
  184. getgoal(dlp) register LINE *dlp; {
  185.     register int    c;
  186.     register int    col;
  187.     register int    newcol;
  188.     register int    dbo;
  189.  
  190.     col = 0;
  191.     dbo = 0;
  192.     while (dbo != llength(dlp)) {
  193.         c = lgetc(dlp, dbo);
  194.         newcol = col;
  195.         if (
  196. #ifdef    NOTAB
  197.             !(mode&MNOTAB) &&
  198. #endif
  199.             c == '\t')
  200.             newcol |= 0x07;
  201.         else if (ISCTRL(c) != FALSE)
  202.             ++newcol;
  203.         ++newcol;
  204.         if (newcol > curgoal)
  205.             break;
  206.         col = newcol;
  207.         ++dbo;
  208.     }
  209.     return (dbo);
  210. }
  211.  
  212. /*
  213.  * Scroll forward by a specified number
  214.  * of lines, or by a full page if no argument.
  215.  * The "2" is the window overlap (this is the default
  216.  * value from ITS EMACS). Because the top line in
  217.  * the window is zapped, we have to do a hard
  218.  * update and get it back.
  219.  */
  220. /*ARGSUSED*/
  221. forwpage(f, n, k) register int n; {
  222.     register LINE    *lp;
  223.  
  224.     if (f == FALSE) {
  225.         n = curwp->w_ntrows - 2;    /* Default scroll.    */
  226.         if (n <= 0)            /* Forget the overlap    */
  227.             n = 1;            /* if tiny window.    */
  228.     } else if (n < 0)
  229.         return (backpage(f, -n, KRANDOM));
  230. #ifdef    CVMVAS
  231.     else                    /* Convert from pages    */
  232.         n *= curwp->w_ntrows;        /* to lines.        */
  233. #endif
  234.     lp = curwp->w_linep;
  235.     while (n-- && lp!=curbp->b_linep)
  236.         lp = lforw(lp);
  237.     curwp->w_linep = lp;
  238.     curwp->w_dotp  = lp;
  239.     curwp->w_doto  = 0;
  240.     curwp->w_flag |= WFHARD;
  241.     return (TRUE);
  242. }
  243.  
  244. /*
  245.  * This command is like "forwpage",
  246.  * but it goes backwards. The "2", like above,
  247.  * is the overlap between the two windows. The
  248.  * value is from the ITS EMACS manual. The
  249.  * hard update is done because the top line in
  250.  * the window is zapped.
  251.  */
  252. /*ARGSUSED*/
  253. backpage(f, n, k) register int n; {
  254.     register LINE    *lp;
  255.  
  256.     if (f == FALSE) {
  257.         n = curwp->w_ntrows - 2;    /* Default scroll.    */
  258.         if (n <= 0)            /* Don't blow up if the    */
  259.             n = 1;            /* window is tiny.    */
  260.     } else if (n < 0)
  261.         return (forwpage(f, -n, KRANDOM));
  262. #ifdef    CVMVAS
  263.     else                    /* Convert from pages    */
  264.         n *= curwp->w_ntrows;        /* to lines.        */
  265. #endif
  266.     lp = curwp->w_linep;
  267.     while (n-- && lback(lp)!=curbp->b_linep)
  268.         lp = lback(lp);
  269.     curwp->w_linep = lp;
  270.     curwp->w_dotp  = lp;
  271.     curwp->w_doto  = 0;
  272.     curwp->w_flag |= WFHARD;
  273.     return (TRUE);
  274. }
  275.  
  276. /*
  277.  * Page the other window. Check to make sure it exists, then
  278.  * nextwind, forwpage and prevwind.
  279.  */
  280. pagenext(f, n, k) {
  281.     if (wheadp->w_wndp == NULL) {
  282.         ewprintf("No other window");
  283.         return FALSE;
  284.     }
  285.     (VOID) nextwind(f, n, k);
  286.     (VOID) forwpage(f, n, k);
  287.     (VOID) prevwind(f, n, k);
  288.     return TRUE;
  289. }
  290.  
  291. /* 
  292.  * Internal set mark routine, used by other functions (daveb).
  293.  */
  294. VOID
  295. isetmark()
  296. {
  297.     curwp->w_markp = curwp->w_dotp;
  298.     curwp->w_marko = curwp->w_doto;
  299. }
  300.  
  301. /*
  302.  * Set the mark in the current window
  303.  * to the value of dot. A message is written to
  304.  * the echo line unless we are running in a keyboard
  305.  * macro, when it would be silly.
  306.  */
  307. /*ARGSUSED*/
  308. setmark(f, n, k) {
  309.     isetmark();
  310.     if (kbdmop == NULL)
  311.         ewprintf("Mark set");
  312.     return (TRUE);
  313. }
  314.  
  315. /*
  316.  * Swap the values of "dot" and "mark" in
  317.  * the current window. This is pretty easy, because
  318.  * all of the hard work gets done by the standard routine
  319.  * that moves the mark about. The only possible
  320.  * error is "no mark".
  321.  */
  322. /*ARGSUSED*/
  323. swapmark(f, n, k) {
  324.     register LINE    *odotp;
  325.     register int    odoto;
  326.  
  327.     if (curwp->w_markp == NULL) {
  328.         ewprintf("No mark in this window");
  329.         return (FALSE);
  330.     }
  331.     odotp = curwp->w_dotp;
  332.     odoto = curwp->w_doto;
  333.     curwp->w_dotp  = curwp->w_markp;
  334.     curwp->w_doto  = curwp->w_marko;
  335.     curwp->w_markp = odotp;
  336.     curwp->w_marko = odoto;
  337.     curwp->w_flag |= WFMOVE;
  338.     return (TRUE);
  339. }
  340.  
  341. /*
  342.  * Go to a specific line, mostly for
  343.  * looking up errors in C programs, which give the
  344.  * error a line number. If an argument is present, then
  345.  * it is the line number, else prompt for a line number
  346.  * to use.
  347.  */
  348. /*ARGSUSED*/
  349. gotoline(f, n, k) register int n; {
  350.     register LINE    *clp;
  351.     register int    s;
  352.     char        buf[32];
  353.  
  354.     if (f == FALSE) {
  355.         if ((s=ereply("Goto line: ", buf, sizeof(buf))) != TRUE)
  356.             return (s);
  357.         n = atoi(buf);
  358.     }
  359.  
  360.     clp = lforw(curbp->b_linep);        /* "clp" is first line    */
  361.     while (n > 1) {
  362.         if (lforw(clp) == curbp->b_linep) break;
  363.         clp = lforw(clp);
  364.         --n;
  365.     }
  366.     curwp->w_dotp = clp;
  367.     curwp->w_doto = 0;
  368.     curwp->w_flag |= WFMOVE;
  369.     return (TRUE);
  370. }
  371.